package com.ljx.chainOfResponsibilityMode;

import lombok.Data;
import org.apache.commons.lang3.ObjectUtils;

/**
 * 责任链模式
 * 定义：
 * 责任链模式是将链中的每一个节点看作是一个对象，每个节点处理的请求不同，且内部自动维护一个下一节点对象。
 * 当一个请求从链式的首段发出时，会沿着链的路径依此传递给每一个节点对象，直至有对象处理这个请求为止。属于行为型模式
 *
 * 应用场景：
 * 多个对象可以处理同一请求，但具体由那个对象处理则在运行时动态决定
 * 在不明确指定接收者的情况下，向多个对象中的一个提交一个请求
 * 可动态指定一组对象处理请求
 *
 *
 * 优点：
 * 将请求与处理解耦
 * 请求处理者（节点对象）只需关注自己感兴趣的请求进行处理即可，对于不感兴趣的请求，直接转发给下一个节点。
 * 具备链式传递处理请求功能，请求发送者无需知晓链路结构，只需等待请求处理结果。
 * 链路结构灵活，可以通过改变链路结构动态的新增或者删除责任。
 * 易于拓展新的请求处理类，符合开闭原则
 *
 * 缺点：
 * 责任链太长或者处理时间太长，会影响整体性能
 * 如果节点对象存在循环引用会造成死循环，导致系统崩溃。
 *
 * 经典案例：
 * javax.servlet.Filter
 * javax.servlet.FilterChain
 *
 * @作者 LJX
 * @日期 2022/12/22 9:33
 */
public class ChainofResponsibilityTest {

    public static void main(String[] args) {
        //创建请求
        Request build = new Request.RequestBuilder().setFrequentOk(Boolean.TRUE).setUpLoggedOn(Boolean.FALSE).build();

        //创建处理器
        RequestFrequentHandler requestFrequentHandler = new RequestFrequentHandler(new LoggingHandler(null));
        if(requestFrequentHandler.process(build)){
            System.out.println("正常");
        }else{
            System.out.println("异常");
        }

    }

}

/**
 * 模拟请求
 */
@Data
class Request{

    private Boolean loggedOn;
    private Boolean frequentOk;
    private Boolean isPermits;
    private Boolean containsSensitiveWord;
    private String requestBody;

    public Request(Boolean loggedOn, Boolean frequentOk, Boolean isPermits, Boolean containsSensitiveWord) {
        this.loggedOn = loggedOn;
        this.frequentOk = frequentOk;
        this.isPermits = isPermits;
        this.containsSensitiveWord = containsSensitiveWord;
    }

    static class RequestBuilder{
        private Boolean loggedOn;
        private Boolean frequentOk;
        private Boolean isPermits;
        private Boolean containsSensitiveWord;

        RequestBuilder setUpLoggedOn(Boolean loggedOn){
            this.loggedOn = loggedOn;
            return this;
        }

        RequestBuilder setFrequentOk(Boolean frequentOk){
            this.frequentOk = frequentOk;
            return this;
        }

        RequestBuilder setUpIsPermits(Boolean isPermits){
            this.isPermits = isPermits;
            return this;
        }

        RequestBuilder setUpContainsSensitiveWord(Boolean containsSensitiveWord){
            this.containsSensitiveWord = containsSensitiveWord;
            return this;
        }

        public Request build(){
            Request request = new Request(loggedOn, frequentOk, isPermits, containsSensitiveWord);
            return request;
        }

    }
}

/**
 * 处理器抽象类
 */
@Data
abstract class Handler{
    Handler next;

    public Handler(Handler next) {
        this.next = next;
    }

    abstract Boolean process(Request request);
}

/**
 * 访问频率处理器
 */
class RequestFrequentHandler extends Handler{

    public RequestFrequentHandler(Handler handler) {
        super(handler);
    }

    @Override
    Boolean process(Request request) {
        //不符合访问频率控制
        if(Boolean.FALSE.equals(request.getFrequentOk())){
            System.out.println("访问频率控制");
            return Boolean.FALSE;
        }

        //未发现下一个节点
        Handler next = getNext();
        if(null ==  next){
            return Boolean.TRUE;
        }

        return next.process(request);
    }
}

/**
 * 登陆处理器
 */
class LoggingHandler extends Handler{

    public LoggingHandler(Handler next) {
        super(next);
    }

    @Override
    Boolean process(Request request) {
        //不符合登陆控制器
        if(Boolean.FALSE.equals(request.getLoggedOn())){
            System.out.println("登陆处理器控制");
            return Boolean.FALSE;
        }

        //未发现下一个节点
        Handler next = getNext();
        if(null ==  next){
            return Boolean.TRUE;
        }

        return next.process(request);
    }
}
